﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Web.Mvc;
using Xenta.Utils;
using Xenta.Attributes;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Catalog.Controllers
{
    [Authenticate, InRole("ADMIN")]
    public sealed class SupplierController : ExtController
    {
        #region GET/POST Actions

        [HttpGet]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet, RestoreState]
        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, PersistState]
        public ActionResult Create(int managerID, int fileGroupID, string[] flags)
        {
            try
            {
                var m = Svc.ProcessOperation("CreateCatalogSupplier", new
                {
                    ManagerID = managerID,
                    FileGroupID = fileGroupID,
                    Flags = flags.Merge(",")
                });
                return RedirectToAction(Loc.Act("Edit").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Create"));
        }

        [HttpGet, RestoreState]
        public ActionResult Edit(int id)
        {
            var m = Svc.ProcessOperation("GetCatalogSupplier", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            return View(m);
        }

        [HttpPost, PersistState]
        public ActionResult Update(int id, int fileGroupID, string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateCatalogSupplier", new
                {
                    EntityID = id,
                    FileGroupID = fileGroupID,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }

            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpGet, PersistState]
        public ActionResult Delete(int id, bool deleteFileGroup)
        {
            try
            {
                Svc.ProcessOperation("DeleteCatalogSupplier", new
                {
                    EntityID = id,
                    DeleteFileGroup = deleteFileGroup
                });
                return RedirectToAction(Loc.Act("Index"));
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id
            }));
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult CreateTranslation(int supplierID,
            int languageID,
            string name,
            string shortDescription,
            string description)
        {
            try
            {
                Svc.ProcessOperation("CreateCatalogSupplierTranslation", new
                {
                    HolderID = supplierID,
                    LanguageID = languageID,
                    Name = HtmlUtility.StripTags(name),
                    ShortDescription = HtmlUtility.StripTags(shortDescription),
                    Description = HtmlUtility.Encode(description)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        [HttpPost, PersistState, ValidateInput(false)]
        public ActionResult UpdateTranslation(int id,
            int supplierID,
            int languageID,
            string name,
            string shortDescription,
            string description)
        {
            try
            {
                Svc.ProcessOperation("UpdateCatalogSupplierTranslation", new
                {
                    EntityID = id,
                    LanguageID = languageID,
                    Name = HtmlUtility.StripTags(name),
                    ShortDescription = HtmlUtility.StripTags(shortDescription),
                    Description = HtmlUtility.Encode(description)
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        [HttpGet, PersistState]
        public ActionResult DeleteTranslation(int id, int supplierID)
        {
            try
            {
                Svc.ProcessOperation("DeleteCatalogSupplierTranslation", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        [HttpPost, PersistState]
        public ActionResult CreateAddress(int supplierID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("CreateCatalogSupplierAddress", new
                {
                    HolderID = supplierID,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        [HttpPost, PersistState]
        public ActionResult UpdateAddress(int id,
            int supplierID,
            int countryID,
            int regionID,
            string city,
            string address1,
            string address2,
            string entityName,
            string contactName,
            string postalCode,
            string phoneNumber,
            string faxNumber,
            string email,
            string website,
            string[] flags)
        {
            try
            {
                Svc.ProcessOperation("UpdateCatalogSupplierAddress", new
                {
                    EntityID = id,
                    CountryID = countryID,
                    RegionID = regionID,
                    City = city,
                    Address1 = address1,
                    Address2 = address2,
                    EntityName = entityName,
                    ContactName = contactName,
                    PostalCode = postalCode,
                    PhoneNumber = phoneNumber,
                    FaxNumber = faxNumber,
                    Email = email,
                    Website = website,
                    Flags = flags.Merge(",")
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        [HttpGet, PersistState]
        public ActionResult DeleteAddress(int id, int supplierID)
        {
            try
            {
                Svc.ProcessOperation("DeleteCatalogSupplierAddress", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Edit").Set(new
            {
                id = supplierID
            }));
        }

        #endregion

        #region AJAX Actions

        [HttpPost]
        public ActionResult Grid(int? page,
            int? rows, 
            string sord, 
            string sidx,
            string searchTerm,
            int? countryID,
            int? regionID,
            int? categoryID,
            int? tagID,
            string attributeIDs,
            string createdFrom,
            string createdTo,
            string flagMask)
        {
            page = page.HasValue ? page.Value - 1 : 0;
            rows = rows.HasValue ? rows.Value : 30;
            sord = sord.Equals("desc") ? "Descending" : "Ascending";

            var m = Svc.ProcessOperation("SearchCatalogSuppliers", new
            {
                Term = new
                {
                    Expression = searchTerm
                },
                CountryID = countryID,
                RegionID = regionID,
                CategoryID = categoryID,
                TagID = tagID,
                AttributeIDs = !String.IsNullOrWhiteSpace(attributeIDs) 
                    ? attributeIDs.Split(',').Select(x => x.ParseAs<Int32>()) 
                    : null,
                FlagMask = flagMask,
                CreatedFrom = !String.IsNullOrWhiteSpace(createdFrom) 
                    ? Svc.DateTime(createdFrom) 
                    : (DateTime?)null,
                CreatedTo = !String.IsNullOrWhiteSpace(createdTo) 
                    ? Svc.DateTime(createdTo) 
                    : (DateTime?)null,
                Index = page * rows,
                Count = rows,
                SortBy = new[] 
                {
                    sidx
                },
                SortDir = sord
            }, new
            {
                DisclosureLevel = "Base",
                DisclosureOptions = new Dictionary<String, String>
                {
                    { "TranslatedTo", JDM.String(Svc.Localization.Language.Code) }
                }.Unload()
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                var t = (i.Translations as IEnumerable<dynamic>)
                    .SingleOrDefault(x => JDM.Int32(x.Language.EntityID) ==
                        JDM.Int32(Svc.Localization.Language.EntityID));
                data.Add(new[] { 
                    JDM.Int32(i.EntityID),
                    t != null ? JDM.String(t.Name) : String.Empty,
                    JDM.Int32(i.CommentCount),
                    JDM.Int32(i.RatingCount),
                    JDM.Byte(i.RatingAverage),
                    JDM.Int32(i.ItemCount)
                });
            }

            return Json(new
            {
                pageIndex = page + 1,
                pageCount = Math.Ceiling(JDM.Double(m.TotalCount) / rows),
                totalCount = JDM.Int64(m.TotalCount),
                data = data.ToArray()
            });
        }

        [HttpPost]
        public ActionResult Autocomplete(string term)
        {
            var m = Svc.ProcessOperation("GetCatalogSupplierDictionary", new
            {
                LanguageID = JDM.Int32(Svc.Localization.Language.EntityID),
                Term = new
                {
                    Expression = String.Format("{0}%", term)
                },
                Count = 10
            });
            var data = new List<Object>();

            foreach(var i in m.Items)
            {
                data.Add(new
                {
                    id = JDM.String(i.Key),
                    value = JDM.String(i.Value)
                });
            }
            return Json(data.ToArray());
        }

        #endregion

        #region Child Actions

        [ChildActionOnly]
        public ActionResult _Ratings(int supplierID)
        {
            dynamic m = new ExpandoObject();

            m.EntityID = supplierID;
            m.Ratings = Svc.ProcessOperation("SearchCatalogSupplierRatings", new
            {
                HolderID = supplierID
            }, new
            {
                DisclosureLevel = "Extended"
            }).Items;

            return PartialView(m);
        }

        [ChildActionOnly]
        public ActionResult _Comments(int supplierID)
        {
            dynamic m = new ExpandoObject();

            m.EntityID = supplierID;
            m.Comments = Svc.ProcessOperation("SearchCatalogSupplierComments", new
            {
                HolderID = supplierID
            }, new
            {
                DisclosureLevel = "Extended"
            }).Items;

            return PartialView(m);
        }

        #endregion
    }
}
